package com.micro.utils;

import com.alibaba.fastjson.JSON;
import com.micro.entity.RequestHeader;
import com.micro.entity.TaskInfo;
import com.micro.entity.bilibili.DataMapDto;
import com.micro.entity.bilibili.video.Data;
import com.micro.entity.bilibili.video.VideoDataMap;
import lombok.extern.slf4j.Slf4j;
import okhttp3.Response;
import org.apache.commons.lang3.StringUtils;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * @author dufen
 * @date 2021-10-29 08:31:57
 * @description
 */
@Slf4j
public class BibiVideoUtil {
    private static final String baseUrl = "https://api.bilibili.com/x/player/pagelist?bvid={bvid}&jsonp=jsonp";
    private static final String videoUrl = "https://api.bilibili.com/x/player/playurl?cid={cid}&bvid={bvid}&qn=80&type=&otype=json&fourk=1&fnver=0&fnval=976&session=f496e70b7aeb6614390674e8d211c423";
    private static final String referer = "https://www.bilibili.com/video/{bvid}?p={page}";

    public static void main(String[] args) throws IOException {
        System.out.println(getTaskInfos("https://www.bilibili.com/video/BV1fU4y1A7VC"));
    }

    /**
     *
     * @param url
     * @return
     */
    public static List<TaskInfo> getTaskInfos(String url) {
        String cachePath = String.valueOf(System.currentTimeMillis());
        String bvid = StringUtils.indexOf(url, "?") > -1
                ? StringUtils.substring(url, StringUtils.lastIndexOf(url, "/") + 1, StringUtils.lastIndexOf(url, "?"))
                : StringUtils.substring(url, StringUtils.lastIndexOf(url, "/") + 1);
        List<BiliBiliVideoInfo> biliBiliVideoInfos = assembleData(bvid);
        List<TaskInfo> taskInfos = new ArrayList<>();
        biliBiliVideoInfos.stream().forEach(biliBiliVideoInfo -> {
            TaskInfo taskInfo = new TaskInfo();
            taskInfo.setUrl(url);
            taskInfo.setCachePath(cachePath);
            taskInfo.setName(biliBiliVideoInfo.getVideoName());
            taskInfo.setBilibiliData(biliBiliVideoInfo.getData());
            String ref = StringUtils.replace(StringUtils.replace(referer, "{bvid}", bvid), "{page}", String.valueOf(biliBiliVideoInfos.indexOf(biliBiliVideoInfo)+1));
            taskInfo.getRequestHeader().addHeader("origin", " https://www.bilibili.com").addHeader("referer", ref);
            taskInfos.add(taskInfo);
        });
        return taskInfos;
    }

    /**
     *
     * @param bvid
     * @return
     */
    public static List<BiliBiliVideoInfo> assembleData(String bvid) {
        List<BiliBiliVideoInfo> list = new ArrayList<>();
        DataMapDto dataMapDto = getBibiVideoData(bvid);
        if (dataMapDto != null && dataMapDto.getData() != null) {
            dataMapDto.getData().stream().map(t -> {
                String cid = t.getCid();
                String fileName = t.getPart();
                String page = t.getPage();
                VideoDataMap videoDataMap = getVideoDataMap(cid, bvid, page);
                if (videoDataMap != null) {
                    BiliBiliVideoInfo biliBiliVideoInfo = new BiliBiliVideoInfo();
                    biliBiliVideoInfo.setVideoName(fileName);
                    biliBiliVideoInfo.setData(videoDataMap.getData());
                    return biliBiliVideoInfo;
                }
                return null;
            }).forEach(list::add);
        }
        return list;
    }

    /**
     * 获取课程列表
     *
     * @return
     */
    public static DataMapDto getBibiVideoData(String bvid) {
        try {
            Response response = HttpUtil.okHttpGet(StringUtils.replace(baseUrl, "{bvid}", bvid), new RequestHeader.Build().build());
            String jsonStr = response.body().string();
            return JSON.parseObject(jsonStr, DataMapDto.class);
        } catch (IOException e) {
            log.info("解析Bibi网页失败:{}", e);
            throw new RuntimeException("解析Bibi网页失败");
        }
    }

    /**
     * 获取课程视频音频信息
     *
     * @param cid
     * @param bvid
     * @param page
     * @return
     */
    public static VideoDataMap getVideoDataMap(String cid, String bvid, String page) {
        if (StringUtils.isBlank(cid) && StringUtils.isBlank(bvid)) {

        }
        String url = StringUtils.replace(StringUtils.replace(videoUrl, "{cid}", cid), "{bvid}", bvid);
        String ref = StringUtils.replace(StringUtils.replace(referer, "{bvid}", bvid), "{page}", page);
        try {
            Response response = HttpUtil.okHttpGet(url, new RequestHeader.Build().build().addHeader("origin", " https://www.bilibili.com").addHeader("referer", ref));
            String jsonStr = response.body().string();
            return JSON.parseObject(jsonStr, VideoDataMap.class);
        } catch (IOException e) {
            e.printStackTrace();
            throw new RuntimeException("解析Bibi网页失败");
        }
    }


    public static class BiliBiliVideoInfo {
        private String videoName;
        private Data data;

        public String getVideoName() {
            return videoName;
        }

        public void setVideoName(String videoName) {
            this.videoName = videoName;
        }

        public Data getData() {
            return data;
        }

        public void setData(Data data) {
            this.data = data;
        }

        @Override
        public String toString() {
            return "BiliBiliVideoInfo{" +
                    "videoName='" + videoName + '\'' +
                    ", data=" + data +
                    '}';
        }
    }


}
